#include "Analysis.h"
#include <iostream>
#include <fstream>
#include "ConfigParser.h"

//Declaration of static members :
std::set<std::string> Analysis::ConfiguredAnalysesList;
//std::set<std::string> Analysis::AnalysesList;


Analysis::Analysis(){
  //effHisto=new TH1F("effHisto","Selection Efficiencies",16,0,16);
  



name="NoName";
doGRL=false;  
}




Analysis::~Analysis(){
  
  TH1FMap.clear();
  TH2FMap.clear();
  //delete effHisto;
  TH1FKeys.clear();
  TH2FKeys.clear();
  Analysis::ConfiguredAnalysesList.erase(name);//Remove the name from the list when we go out of scope
  //Analysis::AnalysesList.erase(name);
  delete evtdata;
  
}


std::map<std::string,TH1F*> Analysis::getTH1FMap(){
  
  return TH1FMap;
}

void Analysis::FillHisto(std::string name,double val){
//First Check TH1Fs and TH2Fs are allocated in the Map.... Then Fill it

	if(TH1FMap[name]!=NULL){
		TH1FMap[name]->Fill(val);
		}
	else{
	std::cerr<<"In Analysis \""<<Analysis::name<<"\" :"<<std::endl;
	std::cerr<<"Histogram: "<< name << " : is not Allocated. EXIT..."<<std::endl;
	exit(8);	
	}
}

void Analysis::FillHisto(std::string name,double val1,double val2){
	if(TH2FMap[name]!=NULL){
		TH2FMap[name]->Fill(val1,val2);
		}
	else{
	std::cerr<<"In Analysis \""<<Analysis::name<<"\" :"<<std::endl;
	std::cerr<<"Histogram: "<<name<< " is not Allocated. EXIT..."<<std::endl;
	exit(8);	
	}
}


void Analysis::Finalize(TString filename){
  //std::cout<<"Finalize Called !"<<std::endl;
  //First Check if the output File exists 
  ifstream rootfile(filename);
  if(rootfile){
	  //std::cout<<"File exists"<<std::endl;
	    TFile *of=new TFile(filename,"UPDATE");//this is needen because : when running analyses in parallel the results of separate analyses are written in the same file in their own directories. So the file must be updated if it already exists
		of->cd();
		of->mkdir(name.c_str());
		of->cd(name.c_str());
		for(unsigned int i=0;i<TH1FMap.size();i++){
    
			TH1FMap[TH1FKeys[i]]->Write();
   
		}
		for(unsigned int i=0;i<TH2FMap.size();i++){
			TH2FMap[TH2FKeys[i]]->Write();
		}
  
		of->Close();
		delete of;
	  
   }
	else{
	  //std::cout<<"File Does not exist"<<std::endl;
	    TFile *of=new TFile(filename,"NEW");
		of->cd();
		of->mkdir(name.c_str());
		of->cd(name.c_str());
		for(unsigned int i=0;i<TH1FMap.size();i++){
    
			TH1FMap[TH1FKeys[i]]->Write();
   
		}
		for(unsigned int i=0;i<TH2FMap.size();i++){
			TH2FMap[TH2FKeys[i]]->Write();
		}
  
		of->Close();
		delete of;
	  }

}

void Analysis::Configure(std::string fname){

ConfigParser *prsr=new ConfigParser();
prsr->ParseAnalysisSettings(fname.c_str());
prsr->ParseTHs(fname.c_str(),"TH1Fs");
prsr->ParseTHs(fname.c_str(),"TH2Fs");


TH1FKeys=prsr->getTH1FKeys();
TH1FMap=prsr->getTH1FMap();
TH2FKeys=prsr->getTH2FKeys();
TH2FMap=prsr->getTH2FMap();


name=prsr->name;
doGRL=prsr->doGRL;
if(!Analysis::ConfiguredAnalysesList.count(name)){
Analysis::ConfiguredAnalysesList.insert(name);
}
else{
std::cout<<"******************Configuration Error***********************"<<std::endl;
std::cerr<<"Analysis names must be unique ! Check your configurations..."<<std::endl;
std::cerr<<"Found duplicate analysis name: "						<<name<<std::endl;	
std::cerr<<"*************************************************************"<<std::endl;
exit(EXIT_FAILURE);
}
//Analysis::AnalysesList.insert(name);
}

void Analysis::SetEvtData(EvtData* anevtdata)
{

  evtdata=anevtdata;
}

EvtData* Analysis::GetEvtdata()
{

  return evtdata;
}

void Analysis::setTree ( TTree* atree)
{
thetree=atree;
}

TTree* Analysis::getTree(){
  return thetree;
}


